home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1992 The Regents of the University of California.
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice and the following
- * two paragraphs appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
- * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
- /*
- modified for real time playing of mpegs, pgriffin
- */
-
- #include "video.h"
- #include "proto.h"
- #include "nextstep.h"
- #include <sys/types.h>
- #include <sys/param.h>
- #include <signal.h>
- #ifndef MIPS
- #include <netinet/in.h>
- #else
- #include <bsd/netinet/in.h>
- #endif
-
- #include "util.h"
-
- /* Define buffer length. */
-
- #define BUF_LENGTH 80000
-
- /* Function return type declarations */
- void usage();
-
- /* External declaration of main decoding call. */
-
- extern VidStream *mpegVidRsrc();
- extern VidStream *NewVidStream();
-
- /* Global file pointer to incoming data. */
- FILE *input;
-
- /* End of File flag. */
- static int EOF_flag = 0;
-
- /* Loop flag. */
- int loopFlag = 0;
-
- /* Quiet flag. */
- int quietFlag = 0;
-
- /* Setjmp/Longjmp env. */
- jmp_buf env;
-
- /* Display image on screen? */
- int noDisplayFlag = 0;
-
- /* speed beyond real time Flag */
- unsigned char speedFlag = 0;
-
- /* magnification Flag */
- float magFlag = 1.0;
-
- /* the file name */
- unsigned char filename[MAXPATHLEN];
-
- /* hold display until further window events */
- unsigned char holdFrame;
- /* draw self flag */
- unsigned char drawFrame;
- /* speed in titlebar */
- unsigned char showSpeed;
- /* timing information */
- double frame_interval;
- int frames_per_sec;
- /* rewind flag */
- unsigned char doRewind;
-
- /*
- /*
- *--------------------------------------------------------------
- *
- * get_more_data --
- *
- * Called by correct_underflow in bit parsing utilities to
- * read in more data.
- *
- * Results:
- * Input buffer updated, buffer length updated.
- * Returns 1 if data read, 0 if EOF, -1 if error.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- int
- get_more_data(buf_start, max_length, length_ptr, buf_ptr)
- unsigned int *buf_start;
- int max_length;
- int *length_ptr;
- unsigned int **buf_ptr;
- {
-
- int length, num_read, i, request;
- unsigned char *buffer, *mark;
- unsigned int *lmark;
-
- if (EOF_flag) return 0;
-
- length = *length_ptr;
- buffer = (unsigned char *) *buf_ptr;
-
- if (length > 0) {
- memcpy((unsigned char *) buf_start, buffer, (length*4));
- mark = ((unsigned char *) (buf_start + length));
- }
- else {
- mark = (unsigned char *) buf_start;
- length = 0;
- }
-
- request = (max_length-length)*4;
-
- num_read = fread( mark, 1, request, input);
-
- /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
- {
- int num_read_rounded;
- unsigned char *index;
-
- num_read_rounded = 4*(num_read/4);
-
- /* this can happen only if num_read<request; i.e. end of file reached */
- if( num_read_rounded < num_read )
- {
- num_read_rounded = 4*( num_read/4+1 );
- /* fill in with zeros */
- for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
- /* advance to the next 4-byte boundary */
- num_read = num_read_rounded;
- }
- }
-
- if (num_read < 0) {
- return -1;
- }
- else if (num_read == 0) {
- *buf_ptr = buf_start;
-
- /* Make 32 bits after end equal to 0 and 32
- bits after that equal to seq end code
- in order to prevent messy data from infinite
- recursion.
- */
-
- *(buf_start + length) = 0x0;
- *(buf_start + length+1) = SEQ_END_CODE;
-
- EOF_flag = 1;
- return 0;
- }
-
- lmark = (unsigned int *) mark;
-
- num_read = num_read/4;
-
- for (i=0; i<num_read; i++) {
- *lmark = htonl(*lmark);
- lmark++;
- }
-
- *buf_ptr = buf_start;
- *length_ptr = length + num_read;
-
- return 1;
- }
-
- /*
- *--------------------------------------------------------------
- *
- * int_handler --
- *
- * Handles Cntl-C interupts..
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
- void
- int_handler()
- {
- if (!quietFlag && loopFlag) {
- fprintf(stderr, "\nDone!\n");
- }
-
- #ifdef ANALYSIS
- if(loopFlag) PrintAllStats();
- #endif
- if(loopFlag) PrintTimeInfo();
-
-
- if (curVidStream != NULL)
- DestroyVidStream(curVidStream);
- exit(1);
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * main --
- *
- * Parses command line, starts decoding and displaying.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void
- main(argc, argv)
- int argc;
- char **argv;
- {
-
- char *name;
- static VidStream *theStream;
- int mark, firstLoop;
-
- /* used to control the frame display rate */
- double ReadSysClock();
- double next_time;
- int frame_ref;
- unsigned char do_frame;
-
- firstLoop = 1;
- mark = 1;
- argc--;
-
- name = "";
- input = stdin;
- noDisplayFlag = 0;
-
- while (argc) {
- if (strcmp(argv[mark], "-nop") == 0) {
- TogglePFlag();
- argc--; mark++;
- } else if (strcmp(argv[mark], "-nob") == 0) {
- ToggleBFlag();
- argc--; mark++;
- } else if (strcmp(argv[mark], "-display") == 0) {
- name = argv[++mark];
- argc -= 2; mark++;
- }
- else if (strcmp(argv[mark], "-eachstat") == 0) {
- argc--; mark++;
- #ifdef ANALYSIS
- showEachFlag = 1;
- #else
- fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
- exit(1);
- #endif
- }
- else if (strcmp(argv[mark], "-quiet") == 0) {
- argc--; mark++;
- quietFlag = 1;
- }
- else if (strcmp(argv[mark], "-loop") == 0) {
- argc--; mark++;
- loopFlag = 1;
- }
- else if (strcmp(argv[mark], "-no_display") == 0) {
- argc--; mark++;
- noDisplayFlag = 1;
- }
- else if (strcmp(argv[mark], "-fastest") == 0) {
- argc--; mark++;
- speedFlag = 1;
- }
- else if (strcmp(argv[mark], "-mag") == 0){
- argc--; mark++;
- if(sscanf(argv[mark], "%f", &magFlag) >= 0) {argc--;mark++;}
- }
-
- else if (argv[mark][0] == '-') {
- fprintf(stderr, "Un-recognized flag %s\n",argv[mark]);
- usage(argv[0]);
- }
- else {
- input = fopen(argv[mark], "r");
- if (input == NULL) {
- fprintf(stderr, "Could not open file %s\n", argv[mark]);
- usage(argv[0]);
- }
- if(input != NULL) strcpy(filename, argv[mark]);
- argc--; mark++;
- }
- }
-
- signal(SIGINT, int_handler);
-
- init_tables();
- InitColorDither();
-
- if (setjmp(env) != 0) {
-
- DestroyVidStream(theStream);
-
- rewind(input);
-
- EOF_flag = 0;
- curBits = 0;
- bitOffset = 0;
- bufLength = 0;
- bitBuffer = NULL;
- totNumFrames = 0;
- firstLoop = 0;
-
- #ifdef ANALYSIS
- init_stats();
- #endif
-
- }
-
- doRewind = 0;
-
- if(!quietFlag && firstLoop) printf("Initializing... ");
- else if(firstLoop) printf(" "); /* wish I didn't have to do this.
- otherwise, colors are wrong??? */
-
- if((theStream = NewVidStream(BUF_LENGTH)) == NULL){
- if(!quietFlag) fprintf(stderr,"unable to alloc video stream");
- exit(1);
- }
-
- mpegVidRsrc(0, theStream);
-
- if (firstLoop) {
- InitDisplay(curVidStream->h_size, curVidStream->v_size);
- //InitDisplay(curVidStream->mb_width*16, curVidStream->v_size);
-
- /* set up timing information */
- frames_per_sec = 1.0*curVidStream->picture_rate;
- frame_interval = 1.0/(1.0*curVidStream->picture_rate);
- frame_ref = curVidStream->picture.temp_ref;
-
- if(!speedFlag) printf("requested frames/sec = %d\n",
- curVidStream->picture_rate);
- }
-
- realTimeStart = ReadSysClock();
- next_time = ReadSysClock();
-
- while (1) {
- if(ReadSysClock() < next_time) {
- if( (do_frame == 1) || speedFlag){
- /* do another frame */
- frame_ref = curVidStream->picture.temp_ref;
- while(frame_ref == curVidStream->picture.temp_ref){
- mpegVidRsrc(0, theStream);
- }
- do_frame = 0;
- }
- }
- else{
- next_time = next_time + frame_interval;
- do_frame = 1;
- }
- }
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * usage --
- *
- * Print mpeg_play usage
- *
- * Results:
- * None.
- *
- * Side effects:
- * exits with a return value -1
- *
- *--------------------------------------------------------------
- */
-
- void
- usage(s)
- char *s; /* program name */
- {
- fprintf(stderr, "Usage:\n");
- fprintf(stderr, "mpeg_play\n");
- fprintf(stderr, " [-nob]\n");
- fprintf(stderr, " [-nop]\n");
- fprintf(stderr, " [-loop]\n");
- fprintf(stderr, " [-eachstat]\n");
- fprintf(stderr, " [-no_display]\n");
- fprintf(stderr, " [-mag #]\n");
- fprintf(stderr, " [-quiet]\n");
- fprintf(stderr, " file_name\n");
- exit (-1);
- }
-
-
-
- /*
- *--------------------------------------------------------------
- *
- * DoDitherImage --
- *
- * Called when image needs to be dithered. Selects correct
- * dither routine based on info in ditherType.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void
- DoDitherImage(l, Cr, Cb, disp, h, w)
- unsigned char *l, *Cr, *Cb, *disp;
- int h,w;
- {
- ColorDitherImage(l, Cr, Cb, disp, h, w);
- }
-